﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Forms = System.Windows.Forms;
using CANDataIO;
using DataDefine;
using ECANPort;
using HCC = HandyControl.Controls;

using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using UsingEventAggregator.Core;
using System.Threading;
using HandyControl.Properties.Langs;

namespace TLDNs.ViewModels
{

    public struct DoubleIndex
    {
        public int DevIndex { get; set; }
        /// <summary>
        /// 在表格中的Index
        /// </summary>
        public int TableIndex { get; set; }
        public DoubleIndex(int dev, int tab)
        {
            DevIndex = dev;
            TableIndex = tab;
        }
    }

    public class RunParameterDevIndex : BindableBase
    {
        public DoubleIndex Index { get; set; }
        public RunParameter Info { get; set; }
        private bool _Export;
        public bool Export
        {
            get { return _Export; }
            set { SetProperty(ref _Export, value); }
        }

        public string DeviceName { get; set; }
        public RunParameterDevIndex(DoubleIndex index, RunParameter f, string dev)
        {
            Index = index;
            Info = f;
            Export = false;
            DeviceName = dev;
        }
    }

    public struct StartEndIndex
    {
        public int StartIndex { get; set; }
        public int EndIndex { get; set; }
        public StartEndIndex(int s, int e)
        {
            StartIndex = s;
            EndIndex = e;
        }
    }
    class ParameterExportViewModel : CanDevViewModelBase
    {
        public ParameterExportViewModel(IContainerExtension Container, IRegionManager rm, IEventAggregator ea) : base(Container, rm, ea)
        {
            SFM = SFMDocument.Create();
            int C = SFM.Devices.Length;
            int tabindex = 0;
            for (int i = 0; i < C; i++)
            {
                // 只有Add有用
                DeviceColl.Add(new DeviceInfoIndex(i, SFM.Devices[i].DeviceInfo));
                int ParCount = SFM.Devices[i].Parameters.Length;
                Device_SEIndex.Add(i, new StartEndIndex(tabindex, tabindex + ParCount - 1));

                for (int j = 0; j < ParCount; j++)
                {
                    //if (tabindex <= 20)
                    //{
                    DataList.Add(new RunParameterDevIndex(new DoubleIndex(i, tabindex), SFM.Devices[i].Parameters[j], SFM.Devices[i].DeviceInfo.DeviceName));
                    tabindex++;
                    //}
                    //else
                    //{
                    //    break;
                    //}

                }

            }
        }


        protected override void UILoadedCommand_Sub(ResourceDictionary obj)
        {
            base.UILoadedCommand_Sub(obj);
            // AddOthreDataToList();
        }
        private void AddOthreDataToList()
        {

            int C = SFM.Devices.Length;
            int tabindex = 0;
            for (int i = 0; i < C; i++)
            {
                int ParCount = SFM.Devices[i].Parameters.Length;
                for (int j = 0; j < ParCount; j++)
                {
                    if (tabindex > 20)
                    {
                        DataList.Add(new RunParameterDevIndex(new DoubleIndex(i, tabindex), SFM.Devices[i].Parameters[j], SFM.Devices[i].DeviceInfo.DeviceName));
                    }
                    tabindex++;
                }

            }
        }


        private SFMDocument _SFM;
        public SFMDocument SFM
        {
            get { return _SFM; }
            set
            {
                SetProperty(ref _SFM, value);
            }
        }


        private ObservableCollection<DeviceInfoIndex> _DeviceColl = new ObservableCollection<DeviceInfoIndex>();
        public ObservableCollection<DeviceInfoIndex> DeviceColl
        {
            get { return _DeviceColl; }
            set { SetProperty(ref _DeviceColl, value); }
        }
        private ObservableCollection<RunParameterDevIndex> _DataList = new ObservableCollection<RunParameterDevIndex>();
        public ObservableCollection<RunParameterDevIndex> DataList
        {
            get { return _DataList; }
            set { SetProperty(ref _DataList, value); }
        }

        private ObservableCollection<RunParameterDevIndex> _ExportList = new ObservableCollection<RunParameterDevIndex>();
        public ObservableCollection<RunParameterDevIndex> ExportList
        {
            get { return _ExportList; }
            set { SetProperty(ref _ExportList, value); }
        }

        Dictionary<int, StartEndIndex> Device_SEIndex = new Dictionary<int, StartEndIndex>();

        public DelegateCommand<int?> DeviceExportCheckedCommand => new DelegateCommand<int?>(DeviceExportCheckedCommand_sub);
        private void DeviceExportCheckedCommand_sub(int? devIndex)
        {
            if (devIndex != null)
            {
                StartEndIndex se;
                if (Device_SEIndex.TryGetValue(devIndex.Value, out se))
                {
                    for (int i = se.StartIndex; i <= se.EndIndex; i++)
                    {
                        var tmp = DataList[i];
                        tmp.Export = true;
                        DataList[i] = tmp;
                    }
                }
            }
        }
        public DelegateCommand<int?> DeviceExportUnCheckedCommand => new DelegateCommand<int?>(DeviceExportUnCheckedCommand_sub);
        private void DeviceExportUnCheckedCommand_sub(int? devIndex)
        {
            if (devIndex != null)
            {
                StartEndIndex se;
                if (Device_SEIndex.TryGetValue(devIndex.Value, out se))
                {
                    for (int i = se.StartIndex; i <= se.EndIndex; i++)
                    {
                        var tmp = DataList[i];
                        tmp.Export = false;
                        DataList[i] = tmp;
                    }
                }
            }
        }


        public DelegateCommand<int?> ParameterExportCheckedCommand => new DelegateCommand<int?>(ParameterExportCheckedCommand_sub);
        private void ParameterExportCheckedCommand_sub(int? devIndex)
        {
            if (devIndex != null)
            {
                var tmp = DataList[devIndex.Value];
                if (tmp.Export)
                    return;
                tmp.Export = true;
                DataList[devIndex.Value] = tmp;
            }
        }
        public DelegateCommand<int?> ParameterExportUnCheckedCommand => new DelegateCommand<int?>(ParameterExportUnCheckedCommand_sub);
        private void ParameterExportUnCheckedCommand_sub(int? devIndex)
        {
            if (devIndex != null)
            {
                var tmp = DataList[devIndex.Value];
                if (tmp.Export == false)
                    return;
                tmp.Export = false;
                DataList[devIndex.Value] = tmp;
            }
        }

        public enum ExportStauts
        {
            Export_Select,
            Export_Check,
            Export_OK,
        }

        private ExportStauts _ExportStatus;
        public ExportStauts ExportStatus
        {
            get { return _ExportStatus; }
            set
            {
                SetProperty(ref _ExportStatus, value);
                switch (value)
                {
                    case ExportStauts.Export_Select:
                        SelectVis = Visibility.Visible;
                        CheckVis = Visibility.Collapsed;
                        OKVis = Visibility.Collapsed;
                        break;
                    case ExportStauts.Export_Check:
                        SelectVis = Visibility.Collapsed;
                        CheckVis = Visibility.Visible;
                        OKVis = Visibility.Collapsed;
                        break;
                    case ExportStauts.Export_OK:
                        SelectVis = Visibility.Collapsed;
                        CheckVis = Visibility.Collapsed;
                        OKVis = Visibility.Visible;

                        break;
                    default:
                        break;
                }
            }
        }


        private Visibility _SelectVis = Visibility.Visible;
        public Visibility SelectVis
        {
            get { return _SelectVis; }
            set { SetProperty(ref _SelectVis, value); }
        }

        private Visibility _CheckVis = Visibility.Collapsed;
        public Visibility CheckVis
        {
            get { return _CheckVis; }
            set { SetProperty(ref _CheckVis, value); }
        }

        private Visibility _OkVis = Visibility.Collapsed;
        public Visibility OKVis
        {
            get { return _OkVis; }
            set { SetProperty(ref _OkVis, value); }
        }

        /// <summary>
        /// 百分比
        /// </summary>
        private Double _ExportPercentage;
        /// <summary>
        /// 百分比
        /// </summary>
        public Double ExportPercentage
        {
            get { return _ExportPercentage; }
            set { SetProperty(ref _ExportPercentage, value); }
        }


        private void Next(Panel panel)
        {
            foreach (var stepBar in panel.Children.OfType<HCC.StepBar>())
            {
                stepBar.Next();
            }
        }

        private void Prev(Panel panel)
        {
            foreach (var stepBar in panel.Children.OfType<HCC.StepBar>())
            {
                stepBar.Prev();
            }
        }


        public DelegateCommand<Grid> PrevCmd => new DelegateCommand<Grid>(PrevCmd_Sub);
        private void PrevCmd_Sub(Grid g)
        {
            Prev(g);

            switch (ExportStatus)
            {
                case ExportStauts.Export_Select:
                    // 清空导出的项目
                    ExportList.Clear();
                    break;
                case ExportStauts.Export_Check:
                    // 重置导出状态
                    ExportPercentage = 0;
                    ExportStatus = ExportStauts.Export_Select;
                    ExportList.Clear();
                    break;
                case ExportStauts.Export_OK:
                    ExportStatus = ExportStauts.Export_Check;
                    break;
                default:
                    break;
            }
        }

        public DelegateCommand<Grid> NextCmd => new DelegateCommand<Grid>(NextCmd_Sub);
        private void NextCmd_Sub(Grid g)
        {
            Next(g);

            switch (ExportStatus)
            {
                case ExportStauts.Export_Select:
                    ExportStatus = ExportStauts.Export_Check;
                    // 获取导出的项目
                    for (int i = 0; i < DataList.Count; i++)
                    {
                        if (DataList[i].Export)
                        {
                            ExportList.Add(DataList[i]);
                        }
                    }
                    break;
                case ExportStauts.Export_Check:
                    ExportStatus = ExportStauts.Export_OK;
                    App.UIDispatcherDoAction(() => { ExportPercentage = 0; });
                    DataGrid data = (DataGrid)g.Tag;
                    Export(data, ExportList, "DataExport_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-sss.fff") + ".xls");

                    break;
                case ExportStauts.Export_OK:
                    ExportStatus = ExportStauts.Export_OK;
                    ExportList.Clear();
                    break;
                default:
                    break;
            }
        }

        //public Action InfoCmd => new Lazy<Action>(() => new Action(() => Growl.Info("", ""))).Value;
        public void Export(DataGrid data, ObservableCollection<RunParameterDevIndex> ExportList, string _fileName)
        {
            if (data.Items.Count <= 0)
            {
                HCC.Growl.Info($"{LangDic["NoDateExport"]}!");
                return;
            }

            Forms.SaveFileDialog save = new Forms.SaveFileDialog();
            save.Filter = $"Excel{LangDic["File"]}(*.xls)|*.xls";
            save.Title = $"{LangDic["SaveFileTitle"]}";
            save.FileName = _fileName;

            if (save.ShowDialog() == Forms.DialogResult.OK)
            {
                Task.Run(() =>
                {
                    DataTable dt = new DataTable();
                    List<string> headstring = new List<string>();
                    data.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        for (int i = 0; i < data.Columns.Count; i++)
                        {
                            if (data.Columns[i].Visibility == System.Windows.Visibility.Visible)//只导出可见列
                            {
                                string hi = data.Columns[i].Header.ToString();
                                string hi_2 = (string)LangDic[hi];
                                if (hi_2 != null)
                                    hi = hi_2;

                                dt.Columns.Add(hi);//构建表头
                                headstring.Add(hi);
                            }
                        }
                        // 添加表头
                        DataRow headrow = dt.NewRow();
                        for (int j = 0; j < data.Columns.Count; j++)
                        {
                            headrow[j] = headstring[j];
                        }
                        dt.Rows.Add(headrow);
                        App.UIDispatcherDoAction(() => { ExportPercentage = 10; });
                        for (int i = 0; i < ExportList.Count; i++)
                        {
                            DataRow row = dt.NewRow();
                            row[0] = ExportList[i].Index.TableIndex;
                            row[1] = ExportList[i].DeviceName;
                            row[2] = ExportList[i].Info.ParameterName;
                            row[3] = ExportList[i].Info.Value;
                            row[4] = ExportList[i].Info.Min;
                            row[5] = ExportList[i].Info.Max;
                            row[6] = ExportList[i].Info.Default;
                            row[7] = ExportList[i].Info.Unit;
                            row[8] = ExportList[i].Info.ReadAccessLv;
                            row[9] = ExportList[i].Info.WriteAccessLv;
                            dt.Rows.Add(row);
                        }
                        App.UIDispatcherDoAction(() => { ExportPercentage = 50; });

                        List<string> Devheadstring = new List<string>();

                        string DevSheetTitle = $"SFMVersion:{SFM.SFMVersion}  SystemName:{SFM.System}";

                        Devheadstring.Add("DeviceName");
                        Devheadstring.Add("DeviceType");
                        Devheadstring.Add("HWVersion");
                        Devheadstring.Add("HWNumber");
                        Devheadstring.Add("SWAppVersion");
                        Devheadstring.Add("SWBootloaderVersion");
                        Devheadstring.Add("CANNode_ID");
                        Devheadstring.Add("OrderNumber");
                        Devheadstring.Add("ShippingDate");
                        Devheadstring.Add("Notes");

                        Collection<List<string>> DevicesDatas = new Collection<List<string>>(); 
                        for (int i = 0; i < SFM.Devices.Length; i++)
                        {
                            List<string> dev = new List<string>();
                            dev.Add(SFM.Devices[i].DeviceInfo.DeviceName);
                            dev.Add(SFM.Devices[i].DeviceInfo.DeviceType);
                            dev.Add(SFM.Devices[i].DeviceInfo.HWVersion);
                            dev.Add(SFM.Devices[i].DeviceInfo.HWNumber);
                            dev.Add(SFM.Devices[i].DeviceInfo.SWAppVersion);
                            dev.Add(SFM.Devices[i].DeviceInfo.SWBootloaderVersion);
                            dev.Add(SFM.Devices[i].DeviceInfo.CANNode_ID);
                            dev.Add(SFM.Devices[i].AdditionalInfo.ShippingInfo.OrderNumber);
                            dev.Add(SFM.Devices[i].AdditionalInfo.ShippingInfo.ShippingDate.ToString());
                            dev.Add(SFM.Devices[i].AdditionalInfo.Notes);
                            DevicesDatas.Add(dev);
                        }

                        string fileName = save.FileName;
                        Excel2007 excel = new Excel2007();
                        App.UIDispatcherDoAction(() => { ExportPercentage = 51; });
                        excel.Save(fileName, dt, "Sheet1", "DeviceInfoSheet", Devheadstring, DevicesDatas, DevSheetTitle,Properties.Settings.Default.ExportReadOnly);
                        App.UIDispatcherDoAction(() => { ExportPercentage = 100; });
                        ExportList.Clear();
                    }), null);

                });
            }
            else
            {
                HCC.Growl.Info($"{LangDic["SaveFailed"]}");
            }
        }


        protected override void SFMFileIsReLoaded()
        {
            SFM = SFMDocument.Create();
            DeviceColl.Clear();
            DataList.Clear();
            Device_SEIndex.Clear();
            int C = SFM.Devices.Length;
            int tabindex = 0;
            for (int i = 0; i < C; i++)
            {
                // 只有Add有用
                DeviceColl.Add(new DeviceInfoIndex(i, SFM.Devices[i].DeviceInfo));
                int ParCount = SFM.Devices[i].Parameters.Length;
                Device_SEIndex.Add(i, new StartEndIndex(tabindex, tabindex + ParCount - 1));

                for (int j = 0; j < ParCount; j++)
                {
                    //if (tabindex <= 20)
                    //{
                    DataList.Add(new RunParameterDevIndex(new DoubleIndex(i, tabindex), SFM.Devices[i].Parameters[j], SFM.Devices[i].DeviceInfo.DeviceName));
                    tabindex++;
                    //}
                    //else
                    //{
                    //    break;
                    //}

                }

            }
        }

        /// <summary>
        /// 监控选中项
        /// </summary>    
        public DelegateCommand ExportSelectCommand => new DelegateCommand(ExportSelectCommand_Sub);
        private void ExportSelectCommand_Sub()
        {
            if (dg_all != null)
            {
                List<int> Indexs = new List<int>();
                for (int i = 0; i < dg_all.SelectedItems.Count; i++)
                {
                    RunParameterDevIndex item = (RunParameterDevIndex)dg_all.SelectedItems[i];
                    Indexs.Add(item.Index.TableIndex);
                }

                for (int i = 0; i < Indexs.Count; i++)
                {
                    var tmp = DataList[Indexs[i]];
                    tmp.Export = true;
                    DataList[Indexs[i]] = tmp;
                }
            }
        }


        /// <summary>
        /// 取消监控选中项
        /// </summary>    
        public DelegateCommand UnExportSelectCommand => new DelegateCommand(UnExportSelectCommand_Sub);
        private void UnExportSelectCommand_Sub()
        {
            if (dg_all != null)
            {
                List<int> Indexs = new List<int>();
                for (int i = 0; i < dg_all.SelectedItems.Count; i++)
                {
                    RunParameterDevIndex item = (RunParameterDevIndex)dg_all.SelectedItems[i];
                    Indexs.Add(item.Index.TableIndex);
                }

                for (int i = 0; i < Indexs.Count; i++)
                {
                    var tmp = DataList[Indexs[i]];
                    tmp.Export = false;
                    DataList[Indexs[i]] = tmp;
                }
            }
        }

        private DataGrid dg_all;
        /// <summary>
        /// 控件加载
        /// </summary>    
        public DelegateCommand<DataGrid> UILoadedEvent2Command => new DelegateCommand<DataGrid>(UILoadedEvent2Command_Sub);
        private void UILoadedEvent2Command_Sub(DataGrid par)
        {
            dg_all = par;
        }


    }
}
